home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <proto/exec.h>
- #include <intuition/intuition.h>
- #include <intuition/gadgetclass.h>
- #include <proto/intuition.h>
- #include <libraries/gadtools.h>
- #include <proto/gadtools.h>
- #include <dos/dos.h>
- #include <dos/exall.h>
- #include <dos/dostags.h>
- #include <proto/dos.h>
- #include <graphics/gfx.h>
- #include <clib/graphics_protos.h>
- #include <clib/alib_protos.h>
- #include <libraries/asl.h>
- #include <clib/asl_protos.h>
-
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
- #include "rp.h"
-
- #define SIZELISTVIEWCHARS 37
- #define TRUNCATE 50
- #define LVTRUNCATE 25
-
- /* Limitations:
- LIMIT_DIRS (top-level list entries).
- MAX_FILES (total files/dirs in path). */
-
- MODULE void pop(void);
- MODULE void push(STRPTR name, ULONG theindex);
- MODULE void subdir(ULONG theindex);
- MODULE void parent(void);
- MODULE void root(void);
- MODULE void pathasl(void);
- MODULE void pathstring(void);
- MODULE void comma(ULONG value);
- MODULE ABOOL dirasl(void);
- MODULE void showduplicates(void);
- MODULE void addduplicate(STRPTR path, STRPTR filename);
- MODULE void flipfind(ABOOL keyboard);
- MODULE void clearlist(struct List* ListPtr);
- MODULE void writeline(void);
-
- IMPORT struct Library* ListBrowserBase;
- IMPORT ABOOL fillwindows;
- IMPORT TEXT asldir[VLONGFIELD + 1],
- aslresult[MEDFIELD + 1];
- // we only use LIMIT_DIRS worth of FileNamePtrs.
- MODULE STRPTR FileNamePtr[LIMIT_FILES];
- MODULE STRPTR DirNamePtr[LIMIT_DIRS];
- MODULE TEXT logstring[256 + 1];
- MODULE UBYTE valuestring[11],
- commastring[14];
- IMPORT SBYTE page;
- IMPORT ULONG wbval;
- MODULE ULONG DirNamesAllocated = 0,
- FileNamesAllocated = 0;
- IMPORT TEXT globalname[VLONGFIELD + 1];
- IMPORT TEXT weekdaystring[10],
- datestring[10],
- timestring[9];
- IMPORT struct SharedStruct shared;
- IMPORT struct NewGadget Gadget;
- IMPORT struct Screen* ScreenPtr;
- IMPORT struct Window* MainWindowPtr;
- IMPORT struct Gadget *BU99_Left,
- *BU99_Right,
- *ST99_Output,
- *BU99_OutputASL,
- *CB99_Log,
- *BU99_Update,
- *BU99_Stop,
- *GListPtr,
- *PrevGadPtr;
- IMPORT struct ExAllData* EADataPtr;
- IMPORT WORD ysize;
-
- #define MAX_FILES (128 * 1024)
-
- MODULE struct List EmptyList, SizeList, SizeResultList;
- MODULE struct Gadget *LV81_DupListview = NULL,
- *LV81_Listview = NULL,
- *CB81_Find = NULL,
- *ST81_Path = NULL,
- *BU81_PathASL = NULL,
- *BU81_Root = NULL,
- *BU81_Parent = NULL,
- *TE81_Total = NULL,
- *TE81_Free = NULL;
- MODULE ULONG dup = 0;
- MODULE STRPTR* TablePtr;
- MODULE UBYTE* OffsetPtr;
- MODULE UBYTE pathlength;
- MODULE BPTR DirHandle = NULL,
- FileHandle = NULL;
-
- MODULE struct
- { ULONG entries, totalbytesval, freeval, stackentries;
- TEXT totalbytesstring[11], freestring[11],
- oldpath[VLONGFIELD + 1], path[VLONGFIELD + 1];
- ULONG bytes[LIMIT_DIRS], topdir[LIMIT_DIRS];
- LONG type[LIMIT_DIRS];
- ABOOL finddup;
- } size;
- MODULE ABOOL stop;
-
- AGLOBAL void size_init(void)
- { strcpy(size.path, "RAM:");
- size.finddup = FALSE;
-
- NewList(&EmptyList);
- }
-
- AGLOBAL void size1(void)
- { if (ysize >= 512)
- { verynewwindow
- ( SIZE1WIDTH, 512, // @@: line up navigation buttons properly
- "Report+: Path Size Report",
- BUTTONIDCMP | STRINGIDCMP | LISTVIEWIDCMP
- );
- } else
- { verynewwindow
- ( SIZE1WIDTH, SIZE1HEIGHT,
- "Report+: Path Size Report",
- BUTTONIDCMP | STRINGIDCMP | LISTVIEWIDCMP
- );
- }
- if (fillwindows)
- { SetAPen(MainWindowPtr->RPort, 0);
- RectFill(MainWindowPtr->RPort, 12, 44, 12 + 348, 44 + 126 - 3); // LV81_Listview
- RectFill(MainWindowPtr->RPort, 228, 168, 228 + 116, 168 + 12); // TE81_Total
- RectFill(MainWindowPtr->RPort, 228, 180, 228 + 116, 180 + 12); // TE81_Free
- if (ysize >= 512)
- { RectFill(MainWindowPtr->RPort, 10, 226, 10 + 620, 226 + 262 - 3); // LV81_DupListview
- } else
- { RectFill(MainWindowPtr->RPort, 370, 116, 370 + 260, 116 + 76); // LV81_DupListview
- } }
-
- if (ysize >= 512)
- { setgadget( 10, 226, 620, 262, NULL, NULL);
- } else
- { setgadget(370, 116, 260, 76, NULL, NULL);
- }
-
- LV81_DupListview = PrevGadPtr = (struct Gadget *) CreateGadget
- ( LISTVIEW_KIND,
- PrevGadPtr,
- &Gadget,
- GTLV_Labels, NULL,
- GTLV_ReadOnly, TRUE,
- GA_Disabled, !size.finddup,
- TAG_DONE
- );
-
- /* path */
- setgadget(60, 20, 270, 12, "_Path:", NULL);
- ST81_Path = PrevGadPtr = (struct Gadget *) CreateGadget
- ( STRING_KIND,
- PrevGadPtr,
- &Gadget,
- GTST_String, &(size.path),
- GTST_MaxChars, VLONGFIELD,
- GA_TabCycle, TRUE,
- GT_Underscore, '_',
- TAG_DONE
- );
- /* path... */
- setgadget(332, 20, 28, 12, "_...", NULL);
- BU81_PathASL = PrevGadPtr = (struct Gadget *) CreateGadget
- ( BUTTON_KIND,
- PrevGadPtr,
- &Gadget,
- GT_Underscore, '_',
- TAG_DONE
- );
- // root
- setgadget(12, 32, 174, 12, "_Root", NULL);
- BU81_Root = PrevGadPtr = (struct Gadget *) CreateGadget
- ( BUTTON_KIND,
- PrevGadPtr,
- &Gadget,
- GT_Underscore, '_',
- TAG_DONE
- );
- // parent
- setgadget(186, 32, 174, 12, "P_arent", NULL);
- BU81_Parent = PrevGadPtr = (struct Gadget *) CreateGadget
- ( BUTTON_KIND,
- PrevGadPtr,
- &Gadget,
- GT_Underscore, '_',
- TAG_DONE
- );
-
- setgadget(12, 44, 348, 126, NULL, NULL);
- LV81_Listview = PrevGadPtr = (struct Gadget *) CreateGadget
- ( LISTVIEW_KIND,
- PrevGadPtr,
- &Gadget,
- GTLV_Labels, NULL,
- TAG_DONE
- );
-
- /* total bytes */
- setgadget(228, 168, 116, 12, "Path bytes:", NULL);
- TE81_Total = PrevGadPtr = (struct Gadget *) CreateGadget
- ( TEXT_KIND,
- PrevGadPtr,
- &Gadget,
- GTTX_Text, size.totalbytesstring,
- GTTX_Border, TRUE,
- TAG_DONE
- );
- /* free bytes */
- setgadget(228, 180, 116, 12, "Free bytes:", NULL);
- TE81_Free = PrevGadPtr = (struct Gadget *) CreateGadget
- ( TEXT_KIND,
- PrevGadPtr,
- &Gadget,
- GTTX_Text, size.freestring,
- GTTX_Border, TRUE,
- TAG_DONE
- );
-
- // log to file?
- setgadget(370, 45, 0, 0, "_Log to file?", PLACETEXT_RIGHT);
- CB99_Log = PrevGadPtr = (struct Gadget *) CreateGadget
- ( CHECKBOX_KIND,
- PrevGadPtr,
- &Gadget,
- GTCB_Checked, shared.log,
- GT_Underscore, '_',
- TAG_DONE
- );
- /* output */
- if (!shared.output[0])
- strcpy(shared.output, "RAM:Report.txt");
- setgadget(370, 72, 230, 12, "_Output pathname:", PLACETEXT_ABOVE);
- ST99_Output = PrevGadPtr = (struct Gadget *) CreateGadget
- ( STRING_KIND,
- PrevGadPtr,
- &Gadget,
- GTST_String, &(shared.output),
- GTST_MaxChars, LONGFIELD,
- GA_TabCycle, TRUE,
- GT_Underscore, '_',
- TAG_DONE
- );
- /* output... */
- setgadget(602, 72, 28, 12, "...", NULL);
- BU99_OutputASL = PrevGadPtr = (struct Gadget *) CreateGadget
- ( BUTTON_KIND,
- PrevGadPtr,
- &Gadget,
- TAG_DONE
- );
-
- // find duplicates?
- if (ysize >= 512)
- { setgadget( 10, 226 - 14, 0, 0, "Find _duplicates?", PLACETEXT_RIGHT);
- } else
- { setgadget(370, 102 , 0, 0, "Find _duplicates?", PLACETEXT_RIGHT);
- }
- CB81_Find = PrevGadPtr = (struct Gadget *) CreateGadget
- ( CHECKBOX_KIND,
- PrevGadPtr,
- &Gadget,
- GTCB_Checked, size.finddup,
- GT_Underscore, '_',
- TAG_DONE
- );
-
- /* update */
- setgadget(370, 20, 60, 12, "_Update", NULL);
- BU99_Update = PrevGadPtr = (struct Gadget *) CreateGadget
- ( BUTTON_KIND,
- PrevGadPtr,
- &Gadget,
- GT_Underscore, '_',
- TAG_DONE
- );
- /* stop */
- setgadget(430, 20, 60, 12, "Stop", NULL);
- BU99_Stop = PrevGadPtr = (struct Gadget *) CreateGadget
- ( BUTTON_KIND,
- PrevGadPtr,
- &Gadget,
- GA_Disabled, TRUE,
- TAG_DONE
- );
-
- drawgadgets((UWORD) ~0);
-
- if (!shared.log)
- { GT_SetGadgetAttrs
- ( ST99_Output,
- MainWindowPtr, NULL,
- GA_Disabled, TRUE,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( BU99_OutputASL,
- MainWindowPtr, NULL,
- GA_Disabled, TRUE,
- TAG_DONE
- );
- }
- updatesize();
- ActivateGadget(ST81_Path, MainWindowPtr, NULL);
- loop();
- strcpy
- ( shared.output,
- ((struct StringInfo *) ST99_Output->SpecialInfo)->Buffer
- );
- closewindow();
- size_exit();
- }
-
- AGLOBAL void updatesize(void)
- { BOOL more; // note that it is BOOL, not ABOOL
- TEXT tempstring1[16], tempstring2[SIZELISTVIEWCHARS + 1],
- tempstring3[VLONGFIELD + 1], tempname[LONGFIELD + 1];
- ULONG i, j, tempbytes;
- LONG templength, temptype; // these both MUST be signed
- ABOOL failed = FALSE;
- struct FileInfoBlock* FIBPtr = NULL;
- struct InfoData* InfoDataPtr = NULL;
- struct ExAllControl* eac = NULL;
- struct ExAllData* ead;
-
- clearlist(&SizeList);
-
- // 1: (Un)ghost relevant gadgets, for duration of the operation.
-
- stop = FALSE;
- GT_SetGadgetAttrs
- ( BU99_Update,
- MainWindowPtr, NULL,
- GA_Disabled, TRUE,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( BU99_Stop,
- MainWindowPtr, NULL,
- GA_Disabled, FALSE,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( BU99_Right,
- MainWindowPtr, NULL,
- GA_Disabled, TRUE,
- TAG_DONE
- );
-
- // 2: Now we get a Lock() on the path.
-
- size.stackentries = size.entries = 0;
- /* From RKRM I&A, p. 65: */
- if
- ( !(DirHandle = (BPTR) Lock(size.path, ACCESS_READ))
- || !(FIBPtr = AllocDosObject(DOS_FIB, NULL))
- || !( Examine(DirHandle, FIBPtr))
- || (FIBPtr->fib_DirEntryType <= 0) // if not a directory
- )
- { failed = TRUE;
- }
-
- strcpy(size.oldpath, size.path);
- if (FIBPtr)
- { FreeDosObject(DOS_FIB, FIBPtr);
- FIBPtr = NULL;
- }
- if (failed)
- { DisplayBeep(ScreenPtr);
- GT_SetGadgetAttrs
- ( BU99_Right,
- MainWindowPtr, NULL,
- GA_Disabled, FALSE,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( BU99_Update,
- MainWindowPtr, NULL,
- GA_Disabled, FALSE,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( BU99_Stop,
- MainWindowPtr, NULL,
- GA_Disabled, TRUE,
- TAG_DONE
- );
- strcpy(size.path, size.oldpath);
- GT_SetGadgetAttrs
- ( ST81_Path,
- MainWindowPtr, NULL,
- GTST_String, size.path,
- TAG_DONE
- );
- return;
- }
-
- GT_SetGadgetAttrs
- ( ST81_Path,
- MainWindowPtr, NULL,
- GTST_String, size.path,
- TAG_DONE
- );
-
- /* 3: Now we call Info() to ascertain the free bytes.
- InfoDataPtr must be longword-aligned. */
-
- if (!(InfoDataPtr = AllocVec(sizeof(struct InfoData), MEMF_CLEAR)))
- { rq("Out of memory!");
- }
- if (Info(DirHandle, InfoDataPtr))
- { size.freeval =
- (InfoDataPtr->id_NumBlocks - InfoDataPtr->id_NumBlocksUsed) *
- InfoDataPtr->id_BytesPerBlock;
- stcl_d(tempstring1, size.freeval);
- templength = 10 - strlen(tempstring1);
- strcpy(size.freestring, "");
- for (i = 1; i <= templength; i++)
- strcat(size.freestring, " ");
- strcat(size.freestring, tempstring1);
- } else strcpy(size.freestring, " ?");
- FreeVec(InfoDataPtr);
- InfoDataPtr = NULL;
-
- /* 4: Now we are ready to begin the main part of the operation.
-
- size.topdir[] = the 'owning' top-level directory for this subdir.
- Top-level dirs are owned by themselves.
- size.bytes[] = the size of this top-level directory/file.
- size.entries = how many top-level dirs, ie. how many names in the
- listview gadget.
- size.path = the path (drive, partition, etc.) the user is doing
- the report on.
- size.stackentries = the current size of the stack.
- DirNamesAllocated = the number of allocated chunks for the
- topdir names. */
-
- dup = 0;
- if (size.finddup)
- { if (!( TablePtr = AllocVec(MAX_FILES * sizeof(STRPTR), NULL)))
- { rq("Out of memory!");
- }
- if (!(OffsetPtr = AllocVec(MAX_FILES * sizeof(UBYTE), NULL)))
- { rq("Out of memory!");
- } }
-
- // This must be allocated with AllocDosObject()
- if (!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
- { rq("Can't allocate DOS object!");
- }
-
- eac->eac_LastKey = 0;
- do
- { more = ExAll(DirHandle, (struct ExAllData *) EADataPtr, 2048, ED_SIZE, eac);
- if (!more && IoErr() != ERROR_NO_MORE_ENTRIES)
- { FreeDosObject(DOS_EXALLCONTROL, eac);
- eac = NULL;
- rq("Can't examine path!");
- }
- if (eac->eac_Entries == 0)
- { ; /* ExAll() failed normally with no entries */
- continue; /* more is USUALLY zero */
- }
-
- // OK, ExAll() has generated up to 2K of data.
- ead = (struct ExAllData *) EADataPtr;
- do
- { /* use ead here */
-
- if (ead->ed_Type == -3 || ead->ed_Type == 2) // if a normal file or normal directory (ie. not a link)
- { size.entries++;
- if (size.entries == LIMIT_DIRS)
- { FreeDosObject(DOS_EXALLCONTROL, eac);
- eac = NULL;
- rq("Overflow!");
- }
- size.type[size.entries] = ead->ed_Type;
- if (size.entries > DirNamesAllocated)
- { if (!(DirNamePtr[DirNamesAllocated + 1] = AllocMem(VLONGFIELD, MEMF_PUBLIC)))
- { FreeDosObject(DOS_EXALLCONTROL, eac);
- eac = NULL;
- rq("Out of memory!");
- }
- DirNamesAllocated++;
- }
- strcpy(DirNamePtr[size.entries], ead->ed_Name);
- if (ead->ed_Type == 2) /* +2 is dir, +3 is softlink, -3 is file */
- { size.bytes[size.entries] = 0;
- strcpy(tempstring3, size.path);
- if (!AddPart(tempstring3, ead->ed_Name, VLONGFIELD))
- { FreeDosObject(DOS_EXALLCONTROL, eac);
- eac = NULL;
- rq("Can't add filename to pathname!");
- }
- push(tempstring3, size.entries);
- } else
- { addduplicate("", ead->ed_Name);
- size.bytes[size.entries] = ead->ed_Size;
- } }
-
- /* get next ead */
- ead = ead->ed_Next;
- } while(ead);
- } while(more);
-
- FreeDosObject(DOS_EXALLCONTROL, eac);
- eac = NULL;
- UnLock(DirHandle);
- DirHandle = NULL;
- pop();
-
- // Now handle the list.
-
- GT_SetGadgetAttrs
- ( LV81_Listview,
- MainWindowPtr,
- NULL,
- GTLV_Labels, (~0),
- TAG_DONE
- );
-
- if (!stop)
- { /* size.entries is the actual number of entries. The array elements are
- from 1 to size.entries.
-
- bubble sort routine */
-
- for (i = size.entries; i >= 2; i--)
- { for (j = 2; j <= i; j++)
- { if (size.bytes[j - 1] < size.bytes[j])
- { // swap them
- tempbytes = size.bytes[j - 1];
- size.bytes[j - 1] = size.bytes[j];
- size.bytes[j] = tempbytes;
- temptype = size.type[j - 1];
- size.type[j - 1] = size.type[j];
- size.type[j] = temptype;
- strcpy(tempname, DirNamePtr[j - 1]);
- strcpy(DirNamePtr[j - 1], DirNamePtr[j]);
- strcpy(DirNamePtr[j], tempname);
- } } }
-
- getdate();
- if (shared.log)
- { tempstring1[0] = QUOTE;
- tempstring1[1] = 0;
-
- strcpy(logstring, "Path: ");
- strcat(logstring, tempstring1);
- strcat(logstring, size.path);
- strcat(logstring, tempstring1);
- strcat(logstring, " at ");
- strcat(logstring, timestring);
- strcat(logstring, " on ");
- strcat(logstring, weekdaystring);
- strcat(logstring, " ");
- strcat(logstring, datestring);
- strcat(logstring, ":\n");
- if (!(FileHandle = (BPTR) Open(shared.output, MODE_READWRITE)))
- rq("Can't open file for appending!");
- Seek(FileHandle, 0, OFFSET_END);
- writeline();
- }
-
- // very long dirnames (truncated ones) are not selectable, unfortunately.
- size.totalbytesval = 0;
- for (i = 1; i <= size.entries; i++)
- { comma(size.bytes[i]);
-
- if (size.type[i] == 2)
- { strcpy(tempstring2, "*");
- strcpy(tempstring3, "*");
- } else
- { strcpy(tempstring2, " ");
- strcpy(tempstring3, " ");
- }
-
- if (strlen(DirNamePtr[i]) > TRUNCATE)
- *(DirNamePtr[i] + TRUNCATE) = 0; // truncate
- strcat(tempstring3, DirNamePtr[i]);
- templength = TRUNCATE + 1 - strlen(DirNamePtr[i]);
- if (templength >= 1)
- for (j = 1; j <= templength; j++)
- strcat(tempstring3, " ");
-
- if (strlen(DirNamePtr[i]) > LVTRUNCATE)
- *(DirNamePtr[i] + LVTRUNCATE) = 0; // truncate
- strcat(tempstring2, DirNamePtr[i]); /* tempstring2 = "*<name>" */
- templength = LVTRUNCATE + 1 - strlen(DirNamePtr[i]);
- if (templength >= 1)
- for (j = 1; j <= templength; j++)
- strcat(tempstring2, " "); /* tempstring2 = "*<name> " */
-
- strcat(tempstring2, commastring);
- strcat(tempstring3, commastring);
-
- AddNameToTail(&SizeList, tempstring2);
- if (shared.log)
- { strcpy(logstring, tempstring3);
- strcat(logstring, "\n");
- writeline();
- }
- size.totalbytesval += size.bytes[i];
- }
-
- comma(size.totalbytesval);
- GT_SetGadgetAttrs
- ( TE81_Total,
- MainWindowPtr, NULL,
- GTTX_Text, commastring,
- TAG_DONE
- );
- comma(size.freeval);
- GT_SetGadgetAttrs
- ( TE81_Free,
- MainWindowPtr,
- NULL,
- GTTX_Text, commastring,
- TAG_DONE
- );
- if (shared.log)
- { strcpy(logstring, "\nPath bytes: ");
- comma(size.totalbytesval);
- strcat(logstring, commastring);
- strcat(logstring, "\nFree bytes: ");
- comma(size.freeval);
- strcat(logstring, commastring);
- strcat(logstring, "\n\n");
- writeline();
- Close(FileHandle);
- FileHandle = NULL;
- }
- showduplicates();
- } else
- { GT_SetGadgetAttrs
- ( TE81_Total,
- MainWindowPtr, NULL,
- GTTX_Text, "",
- TAG_DONE
- );
- comma(size.freeval);
- GT_SetGadgetAttrs
- ( TE81_Free,
- MainWindowPtr,
- NULL,
- GTTX_Text, "",
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( LV81_DupListview,
- MainWindowPtr,
- NULL,
- GTLV_Labels, NULL,
- TAG_DONE
- );
- clearlist(&SizeResultList);
- }
-
- GT_SetGadgetAttrs
- ( LV81_Listview,
- MainWindowPtr,
- NULL,
- GTLV_Labels, &SizeList,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( BU99_Right,
- MainWindowPtr, NULL,
- GA_Disabled, FALSE,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( BU99_Update,
- MainWindowPtr, NULL,
- GA_Disabled, FALSE,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( BU99_Stop,
- MainWindowPtr, NULL,
- GA_Disabled, TRUE,
- TAG_DONE
- );
-
- if (FileHandle) // this is in case the user clicked stop
- { Close(FileHandle);
- FileHandle = NULL;
- }
- while(FileNamesAllocated)
- { FreeMem(FileNamePtr[FileNamesAllocated], VLONGFIELD);
- FileNamePtr[FileNamesAllocated--] = NULL;
- }
- // We need the DirNamePtr[] array to remain valid, because the user
- // can click on the listview gadget.
- }
-
- MODULE void subdir(ULONG topdir)
- { BOOL more;
- TEXT tempstring[VLONGFIELD + 1];
- BPTR DirHandle = NULL;
- struct ExAllControl* eac = NULL;
- struct ExAllData* ead;
-
- /* Instead of passing a pointer to the path, we use a global string.
- There are memory corruption problems if you pass pointers to variables
- which are really local to other functions.
-
- This is dynamically allocated as it must be at least word-aligned;
- also remember not to allocate large arrays on the stack. */
-
- if (!(DirHandle = (BPTR) Lock(globalname, ACCESS_READ)))
- { DisplayBeep(ScreenPtr);
- return;
- }
- if (!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
- { UnLock(DirHandle);
- DirHandle = NULL;
- rq("Can't allocate DOS object!");
- }
-
- eac->eac_LastKey = 0;
- do
- { more = ExAll(DirHandle, (struct ExAllData *) EADataPtr, 2048, ED_SIZE, eac);
- if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES))
- { FreeDosObject(DOS_EXALLCONTROL, eac);
- eac = NULL;
- UnLock(DirHandle);
- DirHandle = NULL;
- rq("Can't examine path!");
- }
- if (eac->eac_Entries == 0)
- { ; /* ExAll() failed normally with no entries */
- continue; /* more is USUALLY zero */
- }
- ead = (struct ExAllData *) EADataPtr;
-
- do
- { /* use ead here */
-
- if (ead->ed_Type == 2) /* +2 is dir, +3 is softlink, -3 is file */
- { strcpy(tempstring, globalname);
- if (!AddPart(tempstring, ead->ed_Name, VLONGFIELD))
- { FreeDosObject(DOS_EXALLCONTROL, eac);
- eac = NULL;
- UnLock(DirHandle);
- DirHandle = NULL;
- rq("Can't add filename to pathname!");
- }
- push(tempstring, topdir);
- } elif (ead->ed_Type == -3) // if it's a file
- { addduplicate(&globalname[pathlength], ead->ed_Name);
- size.bytes[topdir] += ead->ed_Size;
- }
-
- /* get next ead */
- ead = ead->ed_Next;
- } while(ead);
- } while(more);
-
- FreeDosObject(DOS_EXALLCONTROL, eac);
- eac = NULL;
- UnLock(DirHandle);
- DirHandle = NULL;
- // don't call pop() yourself!
- }
-
- MODULE void pop(void)
- { ULONG breakval;
-
- pathlength = strlen(size.path);
- while (size.stackentries && !stop)
- { size.stackentries--;
- strcpy(globalname, FileNamePtr[size.stackentries + 1]);
- subdir(size.topdir[size.stackentries + 1]);
- breakval = checkbreak();
- if (breakval == 2)
- cleanexit(EXIT_SUCCESS);
- elif (breakval == 1)
- stop = TRUE;
- } }
- MODULE void push(STRPTR name, ULONG theindex)
- { size.stackentries++;
- if (size.stackentries == LIMIT_DIRS)
- rq("Overflow!");
- if (size.stackentries > FileNamesAllocated)
- { if (!(FileNamePtr[FileNamesAllocated + 1] = AllocMem(VLONGFIELD, MEMF_PUBLIC)))
- rq("Out of memory!");
- FileNamesAllocated++;
- }
- strcpy(FileNamePtr[size.stackentries], name);
- size.topdir[size.stackentries] = theindex;
- }
-
- AGLOBAL void size_loop(ULONG class, struct Gadget* addr, UWORD code, UWORD qual)
- { UWORD moveto;
-
- if (class == IDCMP_RAWKEY)
- { if (qual & IEQUALIFIER_CONTROL)
- { if (code == SCAN_UP)
- { GT_SetGadgetAttrs
- ( LV81_Listview,
- MainWindowPtr,
- NULL,
- GTLV_Top, 0,
- TAG_DONE
- );
- } elif (code == SCAN_DOWN)
- { if (size.entries > 15) // this number must change
- { moveto = size.entries - 15; // if the height of the
- } else moveto = 0; // listview changes
- GT_SetGadgetAttrs
- ( LV81_Listview,
- MainWindowPtr,
- NULL,
- GTLV_Top, moveto,
- TAG_DONE
- );
- } } }
- elif (class == IDCMP_VANILLAKEY)
- { code = toupper(code);
- if (code == ESCAPE)
- { page = 0;
- } elif (code == 'A')
- parent();
- elif (code == 'R')
- root();
- elif (code == '.')
- pathasl();
- elif (code == 'P')
- { ActivateGadget(ST81_Path, MainWindowPtr, NULL);
- } elif (code == 'L')
- fliplog(TRUE);
- elif (code == 'O')
- { ActivateGadget(ST99_Output, MainWindowPtr, NULL);
- } elif (code == 'U')
- updatesize();
- elif (code == 'D')
- { flipfind(TRUE);
- } }
- elif (class == IDCMP_GADGETUP)
- { /* IDCMP_GADGETUP is sent by the string gadget
- when the user presses RETURN, ENTER, Help, Tab
- or Shift-Tab inside the string gadget. */
-
- if (addr == BU99_Right)
- { page = 0;
- } elif (addr == BU99_Update)
- { updatesize();
- } elif (addr == BU81_PathASL)
- { pathasl();
- } elif (addr == ST81_Path)
- { pathstring();
- } elif (addr == CB99_Log)
- { fliplog(FALSE);
- } elif (addr == ST99_Output)
- { outputstring();
- } elif (addr == BU99_OutputASL)
- { outputasl();
- } elif (addr == BU81_Root)
- { root();
- } elif (addr == BU81_Parent)
- { parent();
- } elif (addr == CB81_Find)
- { flipfind(FALSE);
- } elif (addr == LV81_Listview)
- { /* code is the position within the list, starting from 0. */
-
- if (code + 1 <= size.entries && size.type[code + 1] == 2)
- { if (!(AddPart(size.path, DirNamePtr[code + 1], VLONGFIELD + 1)))
- rq("Can't add filename to pathname!");
- else updatesize();
- } } } }
-
- AGLOBAL void size_exit(void)
- { if (DirHandle)
- { UnLock(DirHandle);
- DirHandle = NULL;
- }
- if (FileHandle)
- { Close(FileHandle);
- FileHandle = NULL;
- }
-
- // Only call this if the list gadget is detached or not present.
- // (ie. after closewindow()).
- clearlist(&SizeList);
- clearlist(&SizeResultList);
-
- while(FileNamesAllocated)
- { FreeMem(FileNamePtr[FileNamesAllocated], VLONGFIELD);
- FileNamePtr[FileNamesAllocated--] = NULL;
- }
- while( DirNamesAllocated)
- { FreeMem( DirNamePtr[ DirNamesAllocated], VLONGFIELD);
- DirNamePtr[ DirNamesAllocated--] = NULL;
- } }
-
- MODULE void parent(void)
- { BPTR DirHandle = NULL,
- ParentHandle = NULL;
-
- if (!(DirHandle = (BPTR) Lock(size.path, ACCESS_READ)))
- rq("Can't lock directory!");
- if (!(ParentHandle = ParentDir(DirHandle)))
- { /* It returned a NULL lock; ie. a lock on SYS:
- That is not what we want. */
- ParentHandle = DirHandle;
- }
- if (!NameFromLock(ParentHandle, size.path, VLONGFIELD))
- rq("Can't get name from lock!");
- UnLock(DirHandle);
- DirHandle = NULL;
-
- updatesize();
- }
-
- MODULE void root(void)
- { BPTR DirHandle = NULL,
- ParentHandle = NULL;
- ABOOL rootdone = FALSE;
-
- if (!(DirHandle = (BPTR) Lock(size.path, ACCESS_READ)))
- rq("Can't lock directory!");
- do
- { if (!(ParentHandle = ParentDir(DirHandle)))
- { /* It returned a NULL lock; ie. a lock on SYS:
- That is not what we want. */
- ParentHandle = DirHandle;
- rootdone = TRUE;
- } else DirHandle = ParentHandle;
- } while (!rootdone);
- if (!NameFromLock(ParentHandle, size.path, VLONGFIELD))
- rq("Can't get name from lock!");
- UnLock(DirHandle);
- DirHandle = NULL;
-
- updatesize();
- }
-
- MODULE void pathasl(void)
- { strcpy(asldir, size.path);
- if (dirasl()) // path for ASL must be valid?
- { strcpy(size.path, aslresult);
- GT_SetGadgetAttrs
- ( ST81_Path,
- MainWindowPtr, NULL,
- GTST_String, size.path,
- TAG_DONE
- );
- updatesize();
- } }
-
- MODULE void pathstring(void)
- { strcpy
- ( size.path,
- ((struct StringInfo *) ST81_Path->SpecialInfo)->Buffer
- );
- updatesize();
- }
-
- MODULE void comma(ULONG value)
- { ABOOL yeah = FALSE;
-
- strcpy(commastring, " , , , ");
- // 1 5 9
-
- valuestring[ 0] = '0' + (value / 1000000000);
- value %= 1000000000;
- if (valuestring[ 0] != '0')
- { commastring[0] = valuestring[0];
- yeah = TRUE;
- } else
- { commastring[ 0] = ' ';
- commastring[ 1] = ' ';
- }
-
- valuestring[ 1] = '0' + (value / 100000000);
- value %= 100000000;
- if (yeah || valuestring[1] != '0')
- { commastring[2] = valuestring[1];
- yeah = TRUE;
- } else commastring[2] = ' ';
-
- valuestring[ 2] = '0' + (value / 10000000);
- value %= 10000000;
- if (yeah || valuestring[2] != '0')
- { commastring[3] = valuestring[2];
- yeah = TRUE;
- } else commastring[3] = ' ';
-
- valuestring[ 3] = '0' + (value / 1000000);
- value %= 1000000;
- if (yeah || valuestring[3] != '0')
- { commastring[4] = valuestring[3];
- yeah = TRUE;
- } else
- { commastring[4] = ' ';
- commastring[5] = ' ';
- }
-
- valuestring[ 4] = '0' + (value / 100000);
- value %= 100000;
- if (yeah || valuestring[4] != '0')
- { commastring[6] = valuestring[4];
- yeah = TRUE;
- } else commastring[6] = ' ';
-
- valuestring[ 5] = '0' + (value / 10000);
- value %= 10000;
- if (yeah || valuestring[5] != '0')
- { commastring[7] = valuestring[5];
- yeah = TRUE;
- } else commastring[7] = ' ';
-
- valuestring[ 6] = '0' + (value / 1000);
- value %= 1000;
- if (yeah || valuestring[6] != '0')
- { commastring[8] = valuestring[6];
- yeah = TRUE;
- } else
- { commastring[8] = ' ';
- commastring[9] = ' ';
- }
-
- valuestring[ 7] = '0' + (value / 100);
- value %= 100;
- if (yeah || valuestring[7] != '0')
- { commastring[10] = valuestring[7];
- yeah = TRUE;
- } else commastring[10] = ' ';
-
- valuestring[ 8] = '0' + (value / 10);
- value %= 10;
- if (yeah || valuestring[8] != '0')
- { commastring[11] = valuestring[8];
- yeah = TRUE;
- } else commastring[11] = ' ';
-
- valuestring[ 9] = '0' + value ;
- commastring[12] = valuestring[9];
- }
-
- MODULE ABOOL dirasl(void)
- { struct FileRequester* ASLRqPtr;
- ABOOL success;
-
- if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "~(#?.info)", ASL_Window, MainWindowPtr, ASL_ExtFlags1, FIL1F_NOFILES, TAG_DONE)))
- { rq("Can't create ASL request!");
- }
- if (AslRequestTags(ASLRqPtr, ASL_Dir, asldir, ASL_Hail, "Report+ path selector", ASL_FuncFlags, FILF_PATGAD, TAG_DONE))
- { strcpy(aslresult, ASLRqPtr->rf_Dir);
- success = TRUE;
- } else success = FALSE;
- FreeAslRequest(ASLRqPtr);
- return(success);
- }
-
- MODULE void showduplicates(void)
- { ULONG breakval, i, j, k;
- ABOOL found = FALSE,
- success;
- struct DateTime DateTime;
- LONG templength;
- struct FileInfoBlock* FIBPtr = NULL;
- TEXT tempstring[VLONGFIELD + 1],
- tempstring2[VLONGFIELD + 1];
-
- DateTime.dat_Format = FORMAT_DOS;
- DateTime.dat_Flags = NULL;
- DateTime.dat_StrDay = NULL;
- DateTime.dat_StrDate = datestring;
- DateTime.dat_StrTime = NULL;
-
- if (size.finddup)
- { GT_SetGadgetAttrs
- ( LV81_DupListview,
- MainWindowPtr,
- NULL,
- GTLV_Labels, NULL,
- TAG_DONE
- );
- clearlist(&SizeResultList);
-
- if (shared.log)
- { strcpy(logstring, "Duplicates found:\n");
- if (!(FileHandle = (BPTR) Open(shared.output, MODE_READWRITE)))
- rq("Can't open file for appending!");
- Seek(FileHandle, 0, OFFSET_END);
- writeline();
- }
- for (i = 0; i <= dup; i++)
- { breakval = checkbreak();
- if (breakval == 2)
- { cleanexit(EXIT_SUCCESS);
- } elif (breakval == 1)
- { stop = TRUE;
- break;
- }
- for (j = 0; j <= dup; j++)
- { if (i != j && !stricmp(TablePtr[i] + OffsetPtr[i], TablePtr[j] + OffsetPtr[j]))
- { found = TRUE;
-
- if (*(TablePtr[i]) != '/')
- { strcpy(tempstring, TablePtr[i]);
- } else
- { strcpy(tempstring, TablePtr[i] + 1);
- }
- if (strlen(tempstring) > TRUNCATE)
- { *(tempstring + TRUNCATE) = 0; // truncate
- }
- templength = TRUNCATE + 1 - strlen(tempstring);
- if (templength >= 1)
- { for (k = 1; k <= templength; k++)
- { strcat(tempstring, " ");
- } }
-
- strcpy(tempstring2, size.path);
- strcat(tempstring2, TablePtr[i]);
- success = FALSE;
- if (DirHandle = (BPTR) Lock(tempstring2, ACCESS_READ))
- { if (FIBPtr = AllocDosObject(DOS_FIB, NULL))
- { success = TRUE;
-
- if (Examine(DirHandle, FIBPtr))
- { comma(FIBPtr->fib_Size);
- strcat(tempstring, commastring);
- } else
- { strcat(tempstring, " ?");
- }
- strcat(tempstring, " ");
-
- DateTime.dat_Stamp = FIBPtr->fib_Date;
- if (DateToStr(&DateTime))
- { strcat(tempstring, datestring);
- } else
- { strcat(tempstring, " ?");
- }
- strcat(tempstring, " ");
-
- FreeDosObject(DOS_FIB, FIBPtr);
- FIBPtr = NULL;
- UnLock(DirHandle);
- DirHandle = NULL;
- } }
- if (!success)
- { strcat(tempstring, " ? ?");
- }
-
- AddNameToTail(&SizeResultList, tempstring);
- if (shared.log)
- { strcpy(logstring, " ");
- strcat(logstring, tempstring);
- strcat(logstring, "\n");
- writeline();
- }
- break;
- } } }
- for (i = 0; i < dup; i++)
- { FreeVec(TablePtr[i]);
- }
- dup = 0;
- FreeVec(OffsetPtr);
- OffsetPtr = NULL;
- FreeVec(TablePtr);
- TablePtr = NULL;
-
- if (shared.log)
- { if (!found)
- { strcat(logstring, " None\n");
- }
- strcat(logstring, "\n");
- writeline();
- Close(FileHandle);
- FileHandle = NULL;
- }
-
- GT_SetGadgetAttrs
- ( LV81_DupListview,
- MainWindowPtr,
- NULL,
- GTLV_Labels, &SizeResultList,
- TAG_DONE
- );
- } }
-
- MODULE void clearlist(struct List* ListPtr)
- { if (!(ListPtr->lh_Head->ln_Succ)) // if list is non-empty
- { FreeNameNodes(ListPtr);
- }
- NewList(ListPtr); // prepare for reuse
- }
-
- MODULE void addduplicate(STRPTR path, STRPTR filename)
- { TEXT tempstring[257];
-
- if (size.finddup)
- { OffsetPtr[dup] = strlen(path);
- strcpy(tempstring, path);
- if (!AddPart(tempstring, filename, 256))
- { rq("AddPart() failed!");
- }
- if (!(TablePtr[dup] = AllocVec(strlen(tempstring) + 1, NULL)))
- { rq("Out of memory!");
- }
- strcpy(TablePtr[dup++], tempstring);
- if (dup >= MAX_FILES)
- { rq("Too many files!");
- } } }
-
- MODULE void flipfind(ABOOL keyboard)
- { if (keyboard)
- { if (CB81_Find->Flags & GFLG_SELECTED)
- { size.finddup = FALSE;
- } else
- { size.finddup = TRUE;
- } }
- else
- { if (CB81_Find->Flags & GFLG_SELECTED)
- { size.finddup = TRUE;
- } else
- { size.finddup = FALSE;
- } }
-
- GT_SetGadgetAttrs
- ( CB81_Find,
- MainWindowPtr, NULL,
- GTCB_Checked, size.finddup,
- TAG_DONE
- );
- GT_SetGadgetAttrs
- ( LV81_DupListview,
- MainWindowPtr, NULL,
- GA_Disabled, !size.finddup,
- TAG_DONE
- );
- }
-
- MODULE void writeline(void)
- { /* The file is opened just before the first call to writeline()
- (when the date, time, etc. is written). Then we keep the file open
- and do our scan. Then we write out the results a line at a time,
- then the free and total bytes, then close the file.
- If we are also doing duplicates, we now do our thinking, and then
- reopen the file, write the results a line at a time, then close the
- file. */
-
- if (FPuts(FileHandle, logstring))
- { Close(FileHandle);
- rq("Can't append to file!");
- } }
-